//
// Created by tcj on 2021/12/2.
//
#include <sstream>
#include <functional>
#include "log.h"
#include "map"
#include "time.h"
#include "string.h"
#include "stdarg.h"
#include "config.h"



namespace sylar{
    const char *LogLevel::Tostring(LogLevel::Level level) {
        switch(level){
#define XX(name) \
        case LogLevel::name: \
            return #name;        \
            break;
        XX(DEBUG);
        XX(INFO);
        XX(WARN);
        XX(ERROR);
        XX(FATAL);
#undef XX
        default:
            return "UNKNOW";
        }
        return "UNKNOW";
    }

    LogLevel::Level LogLevel::Fromstring(const std::string &str) {
#define XX(level,v) \
        if(str == #v){ \
            return LogLevel::level;         \
        }

        XX(DEBUG,debug);
        XX(INFO,info);
        XX(WARN,warn);
        XX(ERROR,error);
        XX(FATAL,fatal);

        XX(DEBUG,DEBUG);
        XX(INFO,INFO);
        XX(WARN,WARN);
        XX(ERROR,ERROR);
        XX(FATAL,FATAL);
        return LogLevel::UNKNOW;
#undef XX
    }
    LogEventWarp::LogEventWarp(LogEvent::ptr e)
        :m_event(e){
    }

    LogEventWarp::~LogEventWarp() {
        m_event->getLogger()->log(m_event->getLevel(),m_event);
    }

    void LogEvent::format(const char* fmt, ...) {
        va_list al;
        va_start(al, fmt);
        format(fmt,al);
        va_end(al);
    }

    void LogEvent::format(const char* fmt,va_list al) {
        char* buf = nullptr;
        int len = vasprintf(&buf,fmt,al);
        if(len!=-1)
        {
            m_ss << std::string(buf,len);
            free(buf);
        }
    }
    std::stringstream& LogEventWarp::getSS() {
        return m_event->getSS();
    }

    void LoggAppender::setFormatter(LogFormatter::ptr val) {
        Mutextype::Lock lock(m_mutex);
        m_formatter = val;
        if(m_formatter){
            m_hasFormatter = true;
        }else{
            m_hasFormatter = false;
        }
    }

    LogFormatter::ptr LoggAppender::getFormatter() {
        Mutextype::Lock lock(m_mutex);
        return m_formatter;
    }

    class MessageFormatItem : public LogFormatter::FormatItem{
    public:
        MessageFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event){
            os<<event->getContent();
        }
    };

    class LevelFormatItem : public LogFormatter::FormatItem{
    public:
        LevelFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<LogLevel::Tostring(level);
        }
    };

    class ElapseFormatItem : public LogFormatter::FormatItem{
    public:
        ElapseFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getElapse();
        }
    };
    class NameFormatItem : public LogFormatter::FormatItem{
    public:
        NameFormatItem(const std::string& str=""){}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getLogger()->getName();
        }
    };


    class ThreadIdFormatItem : public LogFormatter::FormatItem{
    public:
        ThreadIdFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getThread();
        }
    };

    class FriberIdFormatItem : public LogFormatter::FormatItem{
    public:
        FriberIdFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getFiberId();
        }
    };

    class ThreadNameFormatItem : public LogFormatter::FormatItem {
    public:
        ThreadNameFormatItem(const std::string& str = "") {}
        void format(std::ostream& os, Logger::ptr logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << event->getThreadName();
        }
    };

    class DateTimeFormatItem : public LogFormatter::FormatItem{
    public:
        DateTimeFormatItem(const std::string& format="%Y-%m-%d %H:%M:%S")
                :m_format(format){
            if(m_format.empty())
            {
                m_format = "%Y-%m-%d %H:%M:%S";
            }
        }
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            struct tm tm;
            time_t time = event->getTime();
            localtime_r(&time,&tm);
            char buf[64];
            strftime(buf,sizeof(buf),m_format.c_str(),&tm);
            os<<buf;
        }

    private:
        std::string m_format;
    };

    class FileNameFormatItem : public LogFormatter::FormatItem{
    public:
        FileNameFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getFile();
        }
    };

    class LineFormatItem : public LogFormatter::FormatItem{
    public:
        LineFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<event->getLine();
        }
    };

    class NewLineFormatItem : public LogFormatter::FormatItem{
    public:
        NewLineFormatItem(const std::string& str = "") {}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<std::endl;
        }
    };

    class StringFormatItem :public LogFormatter::FormatItem{
    public:
        StringFormatItem(const std::string& str)
            :m_string(str){}
        void format(std::ostream& os,Logger::ptr logger,LogLevel::Level level,LogEvent::ptr event) override{
            os<<m_string;
        }
        ~StringFormatItem(){}

    private:
        std::string m_string;
    };

    class TabFormatItem : public LogFormatter::FormatItem {
    public:
        TabFormatItem(const std::string& str = "") {}
        void format(std::ostream& os, Logger::ptr logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << "\t";
        }
    private:
        std::string m_string;
    };

    LogEvent::LogEvent(std::shared_ptr<Logger> logger,LogLevel::Level level,const char *file, int32_t m_line, uint32_t elapse,
                       uint32_t thresd_id, uint32_t fiberid,uint64_t time,const std::string thread_name)
                       :m_file(file),
                       m_line(m_line),
                       m_elapse(elapse),
                       m_threadId(thresd_id),
                       m_fiberId(fiberid),
                       m_time(time),
                       m_threadName(thread_name),
                       m_logger(logger),
                       m_level(level){}



    //log的实现
    Logger::Logger(const std::string &name)
        :m_name(name)
        ,m_level(LogLevel::DEBUG){
//    p.reset(q) //q为智能指针要指向的新对象
//会令智能指针p中存放指针q，即p指向q的空间，而且会释放原来的空间。（默认是delete）
//      m_formatter.reset(new LogFormatter("%d{%Y-%M-%d %H:%M:%S}%T%t%T%F%T{%p}%T{%c}%T%f:%l%T%m%n"));
        m_formatter.reset(new LogFormatter("%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n"));


    }

    void Logger::setFormatter(LogFormatter::ptr val) {
        Mutextype::Lock lock(m_mutex);
        m_formatter = val;

        for(auto& i:m_Appenders){
            Mutextype::Lock ll(i->m_mutex);
            if(!i->m_hasFormatter){
                i->m_formatter = m_formatter;
            }
        }
    }

    void Logger::setFormatter(const std::string &val) {
        sylar::LogFormatter::ptr new_val(new sylar::LogFormatter(val));
        if(new_val->isError()){
            std::cout<<"Logger setFormatter name="<<m_name<<" value="
                <<val<<" invalid formatter"<<std::endl;
            return ;
        }
//        m_formatter = new_val;
        setFormatter(new_val);
    }

    std::string Logger::toYamlString(){
        Mutextype::Lock lock(m_mutex);
        YAML::Node node;
        node["name"] = m_name;
        if(m_level != LogLevel::UNKNOW){
            node["level"] = LogLevel::Tostring(m_level);
        }
//        node["level"] = LogLevel::Tostring(m_level);
        if(m_formatter){
            node["formatter"] = m_formatter->getPattern();
        }
        for(auto& i:m_Appenders){
            node["appenders"].push_back(YAML::Load(i->toYamlString()));
        }
        std::stringstream ss;
        ss<<node;
        return ss.str();

    }
    LogFormatter::ptr Logger::getFormatter() {
        Mutextype::Lock lock(m_mutex);
        return m_formatter;
    }
    //添加事件
    void Logger::addAppender(LoggAppender::ptr appender){
        Mutextype::Lock lock(m_mutex);
        if(!appender->getFormatter())
        {
            Mutextype::Lock ll(appender->m_mutex);
            appender->m_formatter = m_formatter;
//            appender->setFormatter(m_formatter);
        }
        m_Appenders.push_back(appender);
    }
    //删除事件
    void Logger::delAppender(LoggAppender::ptr appender) {
        Mutextype::Lock lock(m_mutex);
        for(auto it = m_Appenders.begin();it!=m_Appenders.end();it++)
        {
            if(*it == appender){
                m_Appenders.erase(it);
                break;
            }
        }
    }
    void Logger::clearAppenders() {
        Mutextype::Lock lock(m_mutex);
        m_Appenders.clear();
    }

    void Logger::log(LogLevel::Level level, LogEvent::ptr event) {
        if(level>=m_level){
            auto self = shared_from_this();
            Mutextype::Lock lock(m_mutex);
            if(!m_Appenders.empty()){
                for(auto& i:m_Appenders){
                    i->log(self,level,event);
                }
            }else if(m_root){
                m_root->log(level,event);
            }

        }
    }

    void Logger::debug(LogEvent::ptr event) {
        log(LogLevel::DEBUG,event);
    }

    void Logger::error(LogEvent::ptr event) {
        log(LogLevel::ERROR,event);
    }

    void Logger::fatal(LogEvent::ptr event) {
        log(LogLevel::FATAL,event);
    }

    void Logger::info(LogEvent::ptr event) {
        log(LogLevel::INFO,event);
    }

    void Logger::warn(LogEvent::ptr event) {
        log(LogLevel::WARN,event);
    }


    //输出地的实现
    FileLogAppender::FileLogAppender(const std::string &filename)
        :m_filename(filename){
        reopen();
    }

    void FileLogAppender::log(std::shared_ptr<Logger> logger,LogLevel::Level level, LogEvent::ptr event) {
//        每秒钟都可以会进行重新创建文件
        if(level>=m_level){
            uint64_t now = time(0);
            if(now != m_lastTime){
                reopen();
                m_lastTime = now;
            }
            Mutextype::Lock lock(m_mutex);
            if(!(m_filestream << m_formatter->format(logger,level,event))){
                std::cout<<"error"<<std::endl;
            }
        }
    }

    std::string FileLogAppender::toYamlString() {
        Mutextype::Lock lock(m_mutex);
        YAML::Node node;
        node["type"] = "FileLogAppender";
        node["file"] = m_filename;

        if(m_level != LogLevel::UNKNOW){
            node["level"] = LogLevel::Tostring(m_level);
        }
//        node["level"] = LogLevel::Tostring(m_level);
        if(m_hasFormatter && m_formatter){
            node["formatter"] = m_formatter->getPattern();
        }
        std::stringstream ss;
        ss<<node;
        return ss.str();
    }


    //如果文件未打开则打开,打开则关闭之后在打开
    bool FileLogAppender::reopen() {
        Mutextype::Lock lock(m_mutex);
        if(m_filestream){
            m_filestream.close();
        }
        m_filestream.open(m_filename);
        return !m_filestream;
    }
    void StdoutLogAppender::log(std::shared_ptr<Logger> logger,LogLevel::Level level, LogEvent::ptr event) {
        if(level>=m_level){
            Mutextype::Lock lock(m_mutex);
            std::cout<<m_formatter->format(logger,level,event)<<std::endl;
        }
    }

    std::string StdoutLogAppender::toYamlString() {
        Mutextype::Lock lock(m_mutex);
        YAML::Node node;
        node["type"] = "stdoutLogAppender";
        if(m_level != LogLevel::UNKNOW){
            node["level"] = LogLevel::Tostring(m_level);
        }
//        node["level"] = LogLevel::Tostring(m_level);
        if(m_hasFormatter && m_formatter){
            node["formatter"] = m_formatter->getPattern();
        }
        std::stringstream ss;
        ss<<node;
        return ss.str();
    }

//    Formatter的实现


    LogFormatter::LogFormatter(const std::string &pattern)
        :m_pattern(pattern){
        init();
    }

    std::string LogFormatter::format(std::shared_ptr<Logger> logger,LogLevel::Level level,LogEvent::ptr event) {
        std::stringstream ss;
        for(auto& i:m_items){
            i->format(ss,logger,level,event);
        }
        return ss.str();
    }

    std::ostream& LogFormatter::format(std::ostream& ofs, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
        for(auto& i : m_items) {
            i->format(ofs, logger, level, event);
        }
        return ofs;
    }

    //%xxx %xx{xxx} %%
//    解析指导日志格式的格式字符串。，用来指导日志的输出方式
//    %d{%Y-%m-%d %H:%M:%S}%T%t%T%F%T[%p]%T[%c]%T%f:%l%T%m%n
    void LogFormatter::init() {
        //str format type
//        std::cout<<"m_pattern is"<<m_pattern<<std::endl;
        std::vector<std::tuple<std::string,std::string,int>> vec;
        std::string nstr;
        for(size_t i=0;i < m_pattern.size();++i){
            if(m_pattern[i] != '%'){
                nstr.append(1,m_pattern[i]);
                continue;
            }

            if((i+1)<m_pattern.size()){
                if(m_pattern[i+1] == '%'){
                    nstr.append(1,'%');
                    continue;
                }
            }
            size_t n =i+1;
            int fmt_status = 0;
            size_t fmt_begin = 0;

            std::string str;
            std::string fmt;

            while(n<m_pattern.size()){
                if(!fmt_status && !isalpha(m_pattern[n]) && m_pattern[n] !='{' && m_pattern[n] !='}'){
                    str = m_pattern.substr(i + 1, n - i - 1); //可修改
                    break;
                }
                if(fmt_status==0){
                    if(m_pattern[n] == '{'){
                        str = m_pattern.substr(i+1,n-i-1);
                        fmt_status =1; // 解析格式
                        fmt_begin=n;
                        ++n;
                        continue;
                    }
                }else if(fmt_status==1){
                    if(m_pattern[n]=='}'){
                        fmt = m_pattern.substr(fmt_begin+1,n-fmt_begin-1);
                        fmt_status =0;
                        ++n;  //可修改
                        break;
                    }
                }
                ++n;
                if(n == m_pattern.size()) {
                    if(str.empty()) {
                        str = m_pattern.substr(i + 1);
                    }
                }
            }
            if(fmt_status==0){
                if(!nstr.empty()){
                    vec.push_back(std::make_tuple(nstr,std::string(),0));
                    nstr.clear();
                }
//                str = m_pattern.substr(i+1,n-i-1);
                vec.push_back(std::make_tuple(str,fmt,1));
                i=n-1;
            }else if(fmt_status==1){
                std::cout<<"pattern parse error: "<<m_pattern<<"-"<<m_pattern.substr(i)<<std::endl;
                m_error = true;
                vec.push_back(std::make_tuple("<<pattern_error>>",fmt,0));
            }
        }

        if(!nstr.empty()) {
            vec.push_back(std::make_tuple(nstr, "", 0));
        }
//        std::cout<<"nstr1   "<<nstr<<std::endl;
//        if(!nstr.empty()){
//            vec.push_back(std::make_tuple(nstr,"",0));
//        }

//        std::cout<<"nstr2   "<<nstr<<std::endl;
//        for(auto& g:vec){
//            std::cout<<"vec0 "<<std::get<0>(g)<<std::endl;
//            std::cout<<"vec1 "<<std::get<1>(g)<<std::endl;
//            std::cout<<"vec2 "<<std::get<2>(g)<<std::endl;
//        }
//        %d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n



        static std::map<std::string, std::function<FormatItem::ptr(const std::string& str)> > s_format_items = {
#define XX(str, C) \
        {#str, [](const std::string& fmt) { return FormatItem::ptr(new C(fmt));}}
        XX(m, MessageFormatItem),           //m:消息
        XX(p, LevelFormatItem),             //p:日志级别
        XX(r, ElapseFormatItem),            //r:累计毫秒数
        XX(c, NameFormatItem),              //c:日志名称
        XX(t, ThreadIdFormatItem),          //t:线程id
        XX(n, NewLineFormatItem),           //n:换行
        XX(d, DateTimeFormatItem),          //d:时间
        XX(f, FileNameFormatItem),          //f:文件名
        XX(l, LineFormatItem),              //l:行号
        XX(T,TabFormatItem),                //tab
        XX(F,FriberIdFormatItem),            //协程id
        XX(N, ThreadNameFormatItem),        //N:线程名称
#undef XX
        };

        for(auto& i:vec)
        {
            if(std::get<2>(i) ==0)
            {
                m_items.push_back(FormatItem::ptr(new StringFormatItem(std::get<0>(i))));
            }else{
                auto it = s_format_items.find(std::get<0>(i));
                if(it ==s_format_items.end()){
                    m_items.push_back(FormatItem::ptr(new StringFormatItem("<<error_format %" + std::get<0>(i)+">>")));
                    m_error =true;
                }else{
                    m_items.push_back(it->second(std::get<1>(i)));
                }
            }
//            std::cout<< "{"<<std::get<0>(i) <<") - ("<<std::get<1>(i)<<") - ("<<std::get<2>(i)<<")"<<std::endl;
        }
//        std::cout<<m_items.size()<<std::endl;

        //%m -- 消息体
        //%p -- level
        //%r -- 启动后的时间
        //%c -- 日志名称
        //%t -- 线程id
        //%n -- 回车换行init
        //%d -- 时间
        //%f -- 文件名
        //%l -- 行号
    }

    Logger::ptr LoggerManner::getLogger(const std::string& name) {
        Mutextype::Lock lock(m_mutex);
        auto it = m_logger.find(name);
        if(it!=m_logger.end()){
            return it->second;
        }
        Logger::ptr logger(new Logger(name));
        logger->m_root = m_root;
        m_logger[name] = logger;
        return logger;
    }

    LoggerManner::LoggerManner() {
        m_root.reset(new Logger);
        m_root->addAppender(LoggAppender::ptr(new StdoutLogAppender));

        m_logger[m_root->m_name] = m_root;
        init();
    }

    struct LogAppenderDefine{
        int type=0; //1.file  2.stdout
        LogLevel::Level level = LogLevel::UNKNOW;
        std::string formatter;
        std::string file;

        bool operator==(const LogAppenderDefine& oth) const {
            return type == oth.type
                && level == oth.level
                && formatter == oth.formatter
                && file == oth.file;
        }
    };
    struct LogDefine{
        std::string name;
        LogLevel::Level level = LogLevel::UNKNOW;
        std::string formatter;
        std::vector<LogAppenderDefine> appenders;

        bool operator==(const LogDefine& oth) const {
            return name == oth.name
                && level == oth.level
                && formatter == oth.formatter
                && appenders == oth.appenders;
        }
        bool operator<(const LogDefine& oth) const{
            return name<oth.name;
        }
    };

    template<>
    class LexicalCast<std::string,std::set<LogDefine>>{
    public:
        std::set<LogDefine> operator() (const std::string& v){
           YAML::Node node = YAML::Load(v);
           std::set<LogDefine> vec;
           for(size_t i=0;i<node.size();i++){
               auto n = node[i];
               if(!n["name"].IsDefined()){
                   std::cout<<"log config error: name is null, "<<n<<std::endl;
                   continue;
               }
               LogDefine ld;
               ld.name = n["name"].as<std::string>();
               ld.level = LogLevel::Fromstring(n["level"].IsDefined() ? n["level"].as< std::string>() : "");
               if(n["formatter"].IsDefined()){
                   ld.formatter = n["formatter"].as<std::string>();
               }

               if(n["appenders"].IsDefined()){
                   for(size_t x=0;x<n["appenders"].size();x++){
                       auto a = n["appenders"][x];
                       if(!a["type"].IsDefined()){
                           std::cout<<"img config error: appender type is null, "<<a<<std::endl;
                           continue;
                       }
                       std::string  type = a["type"].as<std::string>();
                       LogAppenderDefine lad;
                       if(type == "FileLogAppender"){
                           lad.type =1;
                           if(!a["file"].IsDefined()){
                               std::cout<<"log config error: fileappender file is null, "<<a<<std::endl;
                               continue;
                           }
                           lad.file = a["file"].as<std::string>();
                           if(a["formatter"].IsDefined()){
//                               std::cout<<"******"<<std::endl;
//                               std::cout<<"formatter"<<a["formatter"].as<std::string>()<<std::endl;
                               lad.formatter = a["formatter"].as<std::string>();
                           }
                       }else if(type == "StdoutLogAppender"){
                           lad.type =2;
                           if(a["formatter"].IsDefined()) {
                               lad.formatter = a["formatter"].as<std::string>();
                           }
                       }else {
                           std::cout << "log config error: appender type is invaild, "<<a<<std::endl;
                           continue;
                       }

                       ld.appenders.push_back(lad);
                   }
               }
               vec.insert(ld);
           }
           return vec;
        }
    };


    template<>
    class LexicalCast<std::set<LogDefine>,std::string>{
    public:
        std::string operator() (const std::set<LogDefine>& v){
            YAML::Node node;
            for(auto& i:v){
                YAML::Node n;
                n["name"] = i.name;
                if(i.level != LogLevel::UNKNOW){
                    n["level"] = LogLevel::Tostring(i.level);
                }
                if(!i.formatter.empty()){
                    n["formatter"] = i.formatter;
                }

                for(auto& a : i.appenders){
                    YAML::Node na;
                    if(a.type==1){
                        na["type"] = "FileLogAppender";
                        na["file"] = a.file;
                    }else if(a.type ==2){
                        na["type"] = "StdoutLogAppender";
                    }
                    if(a.level != LogLevel::UNKNOW){
                        n["level"] = LogLevel::Tostring(i.level);
                    }
//                    na["level"] = LogLevel::Tostring(a.level);

                    if(!a.formatter.empty()){
                        na["formatter"] = a.formatter;
                    }
                    n["appenders"].push_back(na);
                }
                node.push_back(n);
            }
            std::stringstream ss;
            ss<<node;
            return ss.str();
        }
    };


    sylar::ConfigVar<std::set<LogDefine>>::ptr g_log_define =
            sylar::Config::Lookup("logs",std::set<LogDefine>(),"logs config");

    struct LogIniter{
        LogIniter(){
            g_log_define->addListener([](const std::set<LogDefine>& old_value,
                    const std::set<LogDefine>& new_value){
                SYLAR_LOG_INFO(SYLAR_LOG_ROOT()) << "on_logger_conf_changed";
                for(auto& i:new_value){
                    auto it = old_value.find(i);
                    sylar::Logger::ptr logger;
                    if(it!=old_value.end()){
                        //新增logger
//                        logger.reset(new sylar::Logger(i.name));
                        logger = SYLAR_LOG_NAME(i.name);
                    }else{
                        if(!(i == *it)){
                            //修改的logger
                            logger = SYLAR_LOG_NAME(i.name);
                        }
                    }
                    logger->setlevel(i.level);
                    if(!i.formatter.empty()){
                        logger->setFormatter(i.formatter);
                    }

                    logger->clearAppenders();
                    for(auto& a : i.appenders){
                        sylar::LoggAppender::ptr ap;
                        if(a.type == 1){
                            ap.reset(new FileLogAppender(a.file));
                        }else if(a.type ==2){
                            ap.reset(new StdoutLogAppender);
                        }
                        ap->setLevel(a.level);
                        if(!a.formatter.empty()){
                            LogFormatter::ptr fmt(new LogFormatter(a.formatter));
                            if(!fmt->isError()){
                                ap->setFormatter(fmt);
                            }else{
                                std::cout<<"log name= "<<i.name<<"appender type="<<a.type<<"formatter"<<a.formatter<<"is invaild"<<std::endl;
                            }
                        }
                        logger->addAppender(ap);
                    }
                }
                for(auto& i: old_value){
                    auto it = new_value.find(i);
                    if(it==new_value.end()){
                        //删除logger
                        auto logger = SYLAR_LOG_NAME(i.name);
                        logger->setlevel((LogLevel::Level)100);
                        logger->clearAppenders();
                    }
                }

            });

        }
    };


    static LogIniter __log_init;

    std::string LoggerManner::toYamlString() {
        Mutextype::Lock lock(m_mutex);
        YAML::Node node;
        for(auto& i:m_logger){
            node.push_back(YAML::Load(i.second->toYamlString()));
        }

        std::stringstream ss;
        ss<<node;
        return ss.str();
    }
    void LoggerManner::init() {

    }




}
